package com.wskj.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wskj.common.core.mybatisplus.core.ServicePlusImpl;
import com.wskj.common.core.page.PagePlus;
import com.wskj.common.core.page.TableDataInfo;
import com.wskj.common.utils.common.AssertUtils;
import com.wskj.common.utils.common.PageUtils;
import com.wskj.system.bo.SysVersionAddBo;
import com.wskj.system.bo.SysVersionEditBo;
import com.wskj.system.bo.SysVersionQueryBo;
import com.wskj.system.domain.SysVersion;
import com.wskj.system.mapper.SysVersionMapper;
import com.wskj.system.service.ISysVersionService;
import com.wskj.system.vo.web.SysVersionVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 版本Service业务层处理
 *
 * @author wsdz
 * @date 2023-02-22
 */
@Service
public class SysVersionServiceImpl extends ServicePlusImpl<SysVersionMapper, SysVersion> implements ISysVersionService {

    @Override
    public SysVersionVo queryById(Long id){
        return getVoById(id, SysVersionVo.class);
    }

    @Override
    public TableDataInfo<SysVersionVo> queryPageList(SysVersionQueryBo bo) {
        PagePlus<SysVersion, SysVersionVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo), SysVersionVo.class);
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<SysVersionVo> queryList(SysVersionQueryBo bo) {
        return listVo(buildQueryWrapper(bo), SysVersionVo.class);
    }

    private LambdaQueryWrapper<SysVersion> buildQueryWrapper(SysVersionQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SysVersion> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getType() != null,SysVersion::getType,bo.getType());
        lqw.like(StrUtil.isNotBlank(bo.getVersionNo()), SysVersion::getVersionNo, bo.getVersionNo());
        lqw.eq(StrUtil.isNotBlank(bo.getContent()), SysVersion::getContent, bo.getContent());
        lqw.eq(StrUtil.isNotBlank(bo.getUrl()), SysVersion::getUrl, bo.getUrl());
        lqw.eq(bo.getForceStatus() != null, SysVersion::getForceStatus, bo.getForceStatus());
        lqw.eq(bo.getStatus() != null, SysVersion::getStatus, bo.getStatus());
        lqw.orderByDesc(SysVersion::getStatus);
        lqw.orderByAsc(SysVersion::getType);
        return lqw;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByAddBo(SysVersionAddBo bo) {
        AssertUtils.notNull(bo.getType(),"type不能为空");
        SysVersion add = BeanUtil.toBean(bo, SysVersion.class);
        StringBuilder versionNo = new StringBuilder();
        versionNo.append("V"+add.getVersionMajor()+".");
        versionNo.append(add.getVersionMinor()+".");
        versionNo.append(add.getVersionPatch());
        add.setVersionNo(versionNo.toString());
        validEntityBeforeSave(add);
        if(bo.getStatus() != null && bo.getStatus()==1){
            LambdaUpdateWrapper<SysVersion> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(SysVersion::getType,bo.getType());
            lambdaUpdateWrapper.set(SysVersion::getStatus,0);
            baseMapper.update(null,lambdaUpdateWrapper);
        }
        return save(add);
    }

    @Override
    public Boolean updateByEditBo(SysVersionEditBo bo) {
        AssertUtils.notNull(bo.getType(),"type不能为空");
        SysVersion update = BeanUtil.toBean(bo, SysVersion.class);
        StringBuilder versionNo = new StringBuilder();
        versionNo.append("V"+update.getVersionMajor()+".");
        versionNo.append(update.getVersionMinor()+".");
        versionNo.append(update.getVersionPatch());
        update.setVersionNo(versionNo.toString());
        validEntityBeforeSave(update);
        if(bo.getStatus() != null && bo.getStatus()==1){
            LambdaUpdateWrapper<SysVersion> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(SysVersion::getType,bo.getType());
            lambdaUpdateWrapper.set(SysVersion::getStatus,0);
            baseMapper.update(null,lambdaUpdateWrapper);
        }
        return updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(SysVersion entity){
        /*LambdaQueryWrapper<SysVersion> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.ne(entity.getId() != null,SysVersion::getId,entity.getId());
        lambdaQueryWrapper.eq(SysVersion::getVersionNo,entity.getVersionNo());
        lambdaQueryWrapper.eq(SysVersion::getType,entity.getType());
        int count = baseMapper.selectCount(lambdaQueryWrapper);
        AssertUtils.isFalse(count>0,"该版本号已存在");*/
        if(entity.getId() == null){
            // 获取最大主版本号
            int selectVersionMajor = baseMapper.getMaxVersionMajor(entity.getType(),null);
            AssertUtils.isTrue(entity.getVersionMajor()>=selectVersionMajor,"主版本号不能小于"+selectVersionMajor);
            // 获取最大次版本号
            int selectVersionMinor = baseMapper.getMaxVersionMinor(entity.getType(),entity.getVersionMajor(),null);
            AssertUtils.isTrue(entity.getVersionMinor()>=selectVersionMinor,"次版本号不能小于"+selectVersionMinor);
            // 获取最大修行版本号
            int selectVersionPatch = baseMapper.getMaxVersionPatch(entity.getType(),entity.getVersionMajor(),entity.getVersionMinor(),null);
            AssertUtils.isTrue(entity.getVersionPatch()>=selectVersionPatch,"修订版本号不能小于"+selectVersionPatch);
        }else{
            if(entity.getStatus() != null && entity.getStatus()==1){
                // 获取最大主版本号
                int selectVersionMajor = baseMapper.getMaxVersionMajor(entity.getType(),1);
                AssertUtils.isTrue(entity.getVersionMajor()>=selectVersionMajor,"当前启用的版本号【"+entity.getVersionNo()+"】不能小于已被启用版本号");
                // 获取最大次版本号
                int selectVersionMinor = baseMapper.getMaxVersionMinor(entity.getType(),entity.getVersionMajor(),1);
                AssertUtils.isTrue(entity.getVersionMinor()>=selectVersionMinor,"当前启用的版本号【"+entity.getVersionNo()+"】不能小于已被启用版本号");
                // 获取最大修行版本号
                int selectVersionPatch = baseMapper.getMaxVersionPatch(entity.getType(),entity.getVersionMajor(),entity.getVersionMinor(),1);
                StringBuilder versionNo = new StringBuilder();
                versionNo.append("V"+selectVersionMajor+".");
                versionNo.append(selectVersionMinor+".");
                versionNo.append(selectVersionPatch);
                AssertUtils.isTrue(entity.getVersionPatch()>=selectVersionPatch,"当前启用的版本号【"+entity.getVersionNo()+"】不能小于已被启用版本号【"+versionNo.toString()+"】");
            }
        }
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }

    @Override
    public String importSysVersion(List<SysVersionVo> sysVersionList) {
        AssertUtils.isTrue(CollectionUtils.isNotEmpty(sysVersionList), "导入数据不能为空");
        int successNum = 0;
        for (SysVersionVo sysVersion : sysVersionList) {
            SysVersion add = BeanUtil.toBean(sysVersion, SysVersion.class);
            save(add);
            successNum++;
        }
        String msg = String.format("导入完成，共计 %d 条数据，成功 %d 条！", sysVersionList.size(), successNum);
        if (successNum != sysVersionList.size()) {
            msg = msg + String.format("失败 %d 条！", sysVersionList.size() - successNum);
        }
        return msg;
    }
}
